package com.fj.flowabletest.demos.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fj.flowabletest.demos.bo.ExpenseBO;
import com.fj.flowabletest.demos.dto.TaskDTO;
import jakarta.servlet.http.HttpServletResponse;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author fj
 * @date 2025/7/11 14:03
 */
@Controller
public class ExpenseFlowController {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private ProcessEngine processEngine;

    @ResponseBody
    @RequestMapping("/expense/start")
    public Object startLeave(@RequestBody ExpenseBO expenseBO){
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("expense", expenseBO);
        ProcessInstance expense = runtimeService.startProcessInstanceByKey("abc", map);
        return String.format("流程启动: %s",expense.getId());
    }

    @ResponseBody
    @RequestMapping("/expense/todo")
    public List<TaskDTO> todoList(@RequestParam("username") String username){
        List<Task> list = taskService.createTaskQuery().taskAssignee(username).list();
        List<TaskDTO> tasks = new ArrayList<>(list.size());
        for (Task task : list){
            TaskDTO dto = new TaskDTO();
            dto.setId(task.getId());
            dto.setName(task.getName());
            dto.setProcessInstanceId(task.getProcessInstanceId());
            dto.setOwner(task.getOwner());
            tasks.add(dto);
        }
        return tasks;
    }

    @ResponseBody
    @RequestMapping("/expense/process/examine")
    public String examineProcess(@RequestParam("taskId") String taskId){
        taskService.complete(taskId);
        return "审批完成";
    }

    @ResponseBody
    @RequestMapping("/expense/process/diagram/{processId}")
    public void processDiagram(@PathVariable ("processId") String processInstanceId, HttpServletResponse response){
        try {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();

            if (processInstance == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Process instance not found");
                return;
            }

            // 获取流程定义
//            ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());

            // 获取流程图输入流
//            InputStream inputStream = repositoryService.getProcessDiagram(processDefinition.getId());

            // 设置响应头
//            response.setContentType("image/png");
//            org.apache.commons.io.IOUtils.copy(inputStream, response.getOutputStream());
//            response.flushBuffer();

            // 获取BPMN模型
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());

            // 获取当前活动节点ID列表
            List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);

            // 生成带有高亮的流程图
            generateHighlightedDiagram(response, bpmnModel, activeActivityIds);
        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error retrieving process diagram");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    @ResponseBody
    @RequestMapping("/expense/process/history/diagram/{processId}")
    public void historyProcessDiagram(@PathVariable("processId") String processInstanceId, HttpServletResponse response){
        try {
            HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();

            if (processInstance == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Historic process instance not found");
                return;
            }

            // 这里需要自定义服务来生成带历史轨迹的流程图
            // 示例代码仅展示接口，实际实现需要根据Flowable API进一步开发
            // InputStream inputStream = customHistoryDiagramService.generateDiagram(processInstanceId);

            // 简化处理，直接返回原始流程图
            ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());
            InputStream inputStream = repositoryService.getProcessDiagram(processDefinition.getId());

            response.setContentType("image/png");
            org.apache.commons.io.IOUtils.copy(inputStream, response.getOutputStream());
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error retrieving historic process diagram");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private void generateHighlightedDiagram(HttpServletResponse response, BpmnModel bpmnModel, List<String> highLightedActivities) throws IOException {
        // 获取流程图表生成器
        ProcessDiagramGenerator diagramGenerator = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();

        // 生成输入流（高亮显示当前活动节点）
        InputStream imageStream = diagramGenerator.generateDiagram(
                bpmnModel,
                "png",
                highLightedActivities,
                new ArrayList<>(), // 高亮的流程线
                "宋体", // 节点标签字体
                "宋体", // 注释字体
                "宋体", // 标题字体
                null, // 类加载器
                1.0, // 缩放因子
                true // 是否生成高亮边框
        );

        // 设置响应头
        response.setContentType("image/png");

        // 将流写入响应
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = imageStream.read(buffer)) != -1) {
            response.getOutputStream().write(buffer, 0, bytesRead);
        }
        response.getOutputStream().flush();
        imageStream.close();
    }

}
